package fudan.se.project.service.infrastructure.func.conference.action.chair;


import fudan.se.project.domain.User;
import fudan.se.project.domain.conference.Conference;
import fudan.se.project.domain.message.Invitation;
import fudan.se.project.service.infrastructure.base.ConferencePermissionService;
import fudan.se.project.service.infrastructure.entity.UserService;
import fudan.se.project.service.infrastructure.entity.message.InvitationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import static fudan.se.project.domain.conference.Conference.ConferenceStage.REVIEW_START;

@Service
public class PcMemberInviteService {

    private UserService userService;
    private ConferencePermissionService conferencePermissionService;

    private InvitationService invitationService;

    @Autowired
    public PcMemberInviteService(UserService userService,
                                 ConferencePermissionService conferencePermissionService,
                                 InvitationService invitationService) {
        this.userService = userService;
        this.conferencePermissionService = conferencePermissionService;
        this.invitationService = invitationService;
    }

    private Collection<User> validateUsers(Collection<String> usernames, Conference conference) {
        boolean isArgumentsCorrect = true;
        List<User> userList = new LinkedList<>();
        for (String username : usernames) {
            User user;
            if ((user = userService.findByUsername(username)) == null) {
                isArgumentsCorrect = false;
                break;
            }

            if (!conferencePermissionService.checkPcMemberPermission(user, conference)) {
                userList.add(user);
            }
        }

        if (!isArgumentsCorrect)
            return new LinkedList<>();
        else
            return userList;
    }

    private boolean isInvitationAlreadySent(Conference conference, User receiver) {
        User sender = conference.getChair().getUser();
        Invitation invitation1 = invitationService.findBySenderAndReceiverWithStateInConference(
                sender,
                receiver,
                conference,
                Invitation.State.WAITING
        );
        Invitation invitation2 = invitationService.findBySenderAndReceiverWithStateInConference(
                sender,
                receiver,
                conference,
                Invitation.State.ACCEPTED
        );

        return invitation1 == null && invitation2 == null;

    }

    public boolean process(Conference conference, Collection<String> usernames) {

        if (
                conference.getState() != Conference.ConferenceState.PASSED
                        || conference.getStage().ordinal() >= REVIEW_START.ordinal()
        ) {
            return false;
        }

        Collection<User> userList = validateUsers(usernames, conference);

        if (userList.isEmpty()) {
            return false;
        } else {
            User sender = conference.getChair().getUser();
            for (User receiver : userList) {

                if (isInvitationAlreadySent(conference, receiver)) {
                    Invitation invitation = new Invitation(sender, receiver, conference);
                    invitationService.save(invitation);
                }

            }
            return true;
        }
    }
}
